package com.hy.mydesktop.client.component.factory;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.BaseTreeLoader;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.data.TreeLoader;
import com.extjs.gxt.ui.client.dnd.DND.Feedback;
import com.extjs.gxt.ui.client.dnd.GridDragSource;
import com.extjs.gxt.ui.client.dnd.GridDropTarget;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreSorter;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.RowEditor;
import com.extjs.gxt.ui.client.widget.treegrid.EditorTreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridCellRenderer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hy.mydesktop.client.GreetingService;
import com.hy.mydesktop.client.GreetingServiceAsync;
import com.hy.mydesktop.client.component.meta.GridModelEnum;
import com.hy.mydesktop.client.rpcModel.RPCTreeModel;
import com.hy.mydesktop.client.rpcModel.RPCTreeModelChildren;
import com.hy.mydesktop.shared.persistence.domain.gxt.GxtComponentMetaNodeModel;

/**
 * 
 * <ul>
 * <li>开发作者：冬超</li>
 * <li>设计日期：2010-8-30；时间：下午01:11:56</li>
 * <li>类型名称：ReorderingGridFactory</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订编号：</b>
 * <li>修订日期：</li>
 * <li>修订作者：</li>
 * <li>修订原因：</li>
 * <li>修订内容：</li>
 * </ul>
 */
public class TreeGridFactory {

	// 表格字段集合
	private static List<ColumnConfig> configs;
	// 拖动
	private static GridDropTarget dropTarget;
	// 后天交互
	private static RpcProxy<List<BaseModel>> proxy;
	// 字段模型
	private static ColumnModel cm;
	// 面板
	private static ContentPanel contentPanel;
	
	private static TreeLoader<BaseModel> loader;

	private static GreetingServiceAsync service = GWT
			.create(GreetingService.class);

	public static ContentPanel Grid(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {

		return configureGrid(gxtComponentMetaNodeModel);

	}

	/**
	 * 
	 * 
	 * @param gxtComponentMetaNodeModel
	 * @return
	 */
	private static ContentPanel configureGrid(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {
		// version需要先赋值
		String table = (String) gxtComponentMetaNodeModel
				.get(GridModelEnum.TABLE.name().toLowerCase());
		Grid<BaseModel> grid = createDefaultBaseGrid(
				(Integer) gxtComponentMetaNodeModel.get(GridModelEnum.VERSION
						.name().toLowerCase()), gxtComponentMetaNodeModel,
				table);

		// 高度
		if (gxtComponentMetaNodeModel.get(GridModelEnum.HIGHT.name()
				.toLowerCase()) != null) {
			Integer height = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.HIGHT.name().toLowerCase());
			grid.setHeight((int) height);

		}
		// 宽度
		if (gxtComponentMetaNodeModel.get(GridModelEnum.WIDTH.name()
				.toLowerCase()) != null) {
			Integer width = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.WIDTH.name().toLowerCase());
			grid.setWidth((int) width);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.ENABLECOLUMNRESIZE
				.name().toLowerCase()) != null) {
			Boolean enableColumnResize = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.ENABLECOLUMNRESIZE.name().toLowerCase());
			grid.setEnableColumnResize(enableColumnResize);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.MINCOLUMNWIDTH.name()
				.toLowerCase()) != null) {
			Integer minColumnWidth = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.MINCOLUMNWIDTH.name().toLowerCase());
			grid.setMinColumnWidth(minColumnWidth);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.AUTOEXPANDCOLUMN.name()
				.toLowerCase()) != null) {
			String autoColumn = (String) gxtComponentMetaNodeModel
					.get(GridModelEnum.AUTOEXPANDCOLUMN.name().toLowerCase());
			grid.setAutoExpandColumn(autoColumn);

		}
		// 需要把方filter加到面板上才能够使用
		if (gxtComponentMetaNodeModel.get(GridModelEnum.FILTER.name()
				.toLowerCase()) != null) {
			StoreFilterField<BaseModel> filter = new StoreFilterField<BaseModel>() {

				@Override
				protected boolean doSelect(Store<BaseModel> store,
						BaseModel parent, BaseModel record, String property,
						String filter) {
					// only match leaf nodes
					if (record instanceof RPCTreeModel) {
						return false;
					}
					String name = record.get("name");
					name = name.toLowerCase();
					if (name.startsWith(filter.toLowerCase())) {
						return true;
					}
					return false;
				}

			};
			TreeStore<BaseModel> treeStore = getTreeStore(table);
			filter.bind(treeStore);
			contentPanel.setTopComponent(filter);
		}

		if (gxtComponentMetaNodeModel.get(GridModelEnum.TRACKMOUSEOVER.name()
				.toLowerCase()) != null) {
			Boolean trackMouseOver = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.TRACKMOUSEOVER.name().toLowerCase());
			grid.setTrackMouseOver(trackMouseOver);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.BORDER.name()
				.toLowerCase()) != null) {
			Boolean show = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.BORDER.name().toLowerCase());
			grid.setBorders(show);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.NUMBER.name()
				.toLowerCase()) != null) {
			Integer number = (Integer) gxtComponentMetaNodeModel
					.get(GridModelEnum.NUMBER.name().toLowerCase());
			int version = gxtComponentMetaNodeModel.get(GridModelEnum.VERSION
					.name().toLowerCase());
			int loaderNumber = gxtComponentMetaNodeModel
					.get(GridModelEnum.LOADERNUMBER.name().toLowerCase());
			getField(configs, number, version, loaderNumber);

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.ROEWEDIT.name()
				.toLowerCase()) != null) {
			RowEditor<ModelData> editor = new RowEditor<ModelData>();
			grid.addPlugin(editor);
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.REODRDER.name()
				.toLowerCase()) != null) {
			new GridDragSource(grid);
			  
			dropTarget = new GridDropTarget(grid);
			dropTarget.setAllowSelfAsSource(true);  
			
		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.FEEBACK.name()
				.toLowerCase()) != null) {
			String back = ((String) gxtComponentMetaNodeModel
					.get(GridModelEnum.FEEBACK.name().toLowerCase()))
					.toUpperCase();
			if (back.equals("APPEND")) {
				dropTarget.setFeedback(Feedback.APPEND);
			} else if (back.equals("BOTH")) {
				dropTarget.setFeedback(Feedback.BOTH);
			} else {
				dropTarget.setFeedback(Feedback.INSERT);
			}

		}
		if (gxtComponentMetaNodeModel.get(GridModelEnum.AllOWSELFASSOURCE
				.name().toLowerCase()) != null) {
			Boolean allowSelfAsSource = (Boolean) gxtComponentMetaNodeModel
					.get(GridModelEnum.AllOWSELFASSOURCE.name().toLowerCase());
			dropTarget.setAllowSelfAsSource(allowSelfAsSource);
		}

		return contentPanel;
	}

	private static Grid<BaseModel> createDefaultBaseGrid(int version,
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel, String table) {
		contentPanel = ContentPanelFactory
				.createContentPanel(gxtComponentMetaNodeModel);
		TreeStore<BaseModel> treestore;
		configs = new ArrayList<ColumnConfig>();

		cm = new ColumnModel(configs);
		if (version == 1) {
			// 可编辑的树形表格
			treestore = getTreeStore(table);
			EditorTreeGrid<BaseModel> grid = new EditorTreeGrid<BaseModel>(
					treestore, cm);
			contentPanel.add(grid);
			loader.load();
			return grid;
		}
		if (version == 2) {
			// 普通树形表格
			treestore = getTreeStore(table);
			TreeGrid<BaseModel> grid = new TreeGrid<BaseModel>(treestore, cm);
			contentPanel.add(grid);
			loader.load();
			return grid;
		} else {
			return null;
		}

	}

	// 表格的字段
	private static List<ColumnConfig> getField(List<ColumnConfig> configs,
			int number, int version, int loaderNumber
			) {
//实现可编辑的表格要在相应的字段上面添加celleditre的属性
		ColumnConfig columnConfig = new ColumnConfig();
		columnConfig.setId("name");
		columnConfig.setHeader("用户名");
		columnConfig.setWidth(100);
		columnConfig.setRenderer(new TreeGridCellRenderer<BaseTreeModel>());
		columnConfig.setEditor(new CellEditor(new TextField<String>()));
		configs.add(columnConfig);
		ColumnConfig columnConfig2 = new ColumnConfig();
		columnConfig2.setId("age");
		columnConfig2.setHeader("年龄");
		columnConfig2.setWidth(100);
		configs.add(columnConfig2);
		
		//configs = GridColumnConfigFactory.createColumnConfigList2(loaderNumber, service);
		return configs;
	}

	// 树形表格的后台数据
	private static TreeStore<BaseModel> getTreeStore(final String table) {
		
		proxy = new RpcProxy<List<BaseModel>>() {

			@Override
			protected void load(Object loadConfig,
					AsyncCallback<List<BaseModel>> callback) {
				service.getTreeModel(table, (RPCTreeModel)loadConfig, callback);
			}
		};
		
		loader = new BaseTreeLoader<BaseModel>(proxy){

			@Override
			public boolean hasChildren(BaseModel parent) {
				
				return parent instanceof RPCTreeModelChildren;
			}
			
		};
		
		TreeStore<BaseModel> treeStore = new TreeStore<BaseModel>(loader);
		treeStore.setStoreSorter(new StoreSorter<BaseModel>(){

			@Override
			public int compare(Store<BaseModel> store, BaseModel m1,
					BaseModel m2, String property) {
				 boolean m1Folder = m1 instanceof RPCTreeModelChildren;  
				        boolean m2Folder = m2 instanceof RPCTreeModelChildren;  
				   
				         if (m1Folder && !m2Folder) {  
				           return -1;  
				        } else if (!m1Folder && m2Folder) {  
				           return 1;  
				         }  
				return super.compare(store, m1, m2, property);
			}
			
		});
			
		treeStore.getLoader().load();
		return treeStore;
	}
}
